package com.fingard.diagnostics.trace;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;
import java.util.HashMap;
import java.util.Vector;

import com.fingard.FGBiz;
import com.fingard.diagnostics.LogHelper;

public class LogQueue {

	//private HashMap<String, Vector<String[]>> mapVector;
	private Vector<String[]> msgList;
	public LogQueue(){
		resetQueue();
	}
	
	public void resetQueue(){
		//mapVector = new HashMap<String, Vector<String[]>>();
		msgList = new Vector<String[]>();
	}
	
	public void add(String[] p_msg){
		//if(mapVector.containsKey(p_logCode)){
		//	Vector<String[]> msgList = new Vector<String[]>();
		//}
		msgList.add(p_msg);
	}
	
	/**最大条目数*/
	private int maxItemCount = 30000;
	private int lastOutputCount = 0;//上次输出日志条数
	public int getLastOutCount(){
		return lastOutputCount;
	}
	public int output(LogTraceFilePath pPathHelper){
		String charset = FGBiz.getDefaultCharset();
		int rdCount = msgList.size();
		if(rdCount == 0){
			return 0;
		}
		if(lastOutputCount>=maxItemCount && rdCount>lastOutputCount){
			String msg = "产生的日志记录数"+rdCount+"已超过最大限制"+maxItemCount+"，并且输出速度赶不上产出速度，本次直接丢弃";
			FGBiz.limitMsg.add("LogTraceOverflow", msg);
			return rdCount;
		}else if(rdCount>=maxItemCount){
			String msg = "产生的日志记录数"+rdCount+"已超过最大限制"+maxItemCount+"，需减少日志产生量";
			FGBiz.limitMsg.add("LogTraceOutputWarning", msg);
		}
		HashMap<String,OutputStreamWriter> wrMap = new HashMap<String,OutputStreamWriter>();
		HashMap<String,FileOutputStream> osMap = new HashMap<String,FileOutputStream>();
		for(int i=0;i<rdCount;i++){
			String[] eachMsg = msgList.get(i);
			String filePath = "";
			try {
				filePath = pPathHelper.getLogFilePath(eachMsg[0],eachMsg[1],eachMsg[2], eachMsg[3].length());
				OutputStreamWriter tmpWriter;
				if(wrMap.containsKey(filePath)){
					tmpWriter = wrMap.get(filePath);
				}else{
					if(wrMap.size()>=30){
						FGBiz.limitMsg.add("LogTraceOutputFileWarning", "同时需要输出的日志文件个数达到"+wrMap.size());
					}
					if(wrMap.size()>=150){//防止文件句柄占用过多
						FGBiz.limitMsg.add("LogTraceOutputFileWarning", "同时需要输出的日志文件个数达到"+wrMap.size());
						clearStreamMap(wrMap, osMap);
						wrMap = new HashMap<String,OutputStreamWriter>();
						osMap = new HashMap<String,FileOutputStream>();
					}
					File tmpFile = new File(filePath);
					File parentDir = new File(tmpFile.getParent());
				    if(!parentDir.exists()){
				    	parentDir.mkdirs();
				    }
				    if(!tmpFile.exists()){
				    	tmpFile.createNewFile();
				    }
				    FileOutputStream fos = new FileOutputStream(tmpFile, true);
				    osMap.put(filePath, fos);
				    tmpWriter = new OutputStreamWriter(fos, charset);
				    wrMap.put(filePath, tmpWriter);
				}
			    tmpWriter.append(eachMsg[3]);
			} catch (UnsupportedEncodingException e) {
				FGBiz.limitMsg.exception("LogQueue", e, filePath);
			} catch (IOException e) {
				FGBiz.limitMsg.exception("LogQueue", e, filePath);
			}
		}
		lastOutputCount = rdCount;
		
		clearStreamMap(wrMap, osMap);
		
		int nowCt = msgList.size();
		if(rdCount != nowCt){
			FGBiz.limitMsg.add("LogTraceOutputError", "输出时日志条数"+rdCount+"与结束时条数"+nowCt+"不一致");
		}
		
		msgList.clear();
		resetQueue();
		return rdCount;
	}
	
	public void clearStreamMap(HashMap<String,OutputStreamWriter> wrMap, HashMap<String,FileOutputStream> osMap){
		for(String eachKey : wrMap.keySet()){
			try {
				OutputStreamWriter eachWr = wrMap.get(eachKey);
				eachWr.close();
			}catch(Exception ex){
				FGBiz.limitMsg.add("LogTraceOutputException", LogHelper.getStackTrace(ex));
			}
		}
		for(String eachKey : osMap.keySet()){
			try {
				FileOutputStream fos = osMap.get(eachKey);
				fos.close();
			}catch(Exception ex){
				FGBiz.limitMsg.add("LogTraceOutputException", LogHelper.getStackTrace(ex));
			}
		}
		
		wrMap.clear();
		wrMap = null;
		
		osMap.clear();
		osMap = null;
	}
}
